import { ElementLocationSizeMap } from './../../../ViewBud/src/desinger/StructElement/StructElement';
import EventManage from '@/core/EventWithDelegateMgr';
export default class $Element {
    private $ele: HTMLElement | HTMLCollectionOf<Element> | null = null;
    protected finder: string | HTMLElement | Element;
    private eventMgr: EventManage;
    constructor(elementTag: string | HTMLElement | Element) {
        this.finder = elementTag;
        if (typeof elementTag == "string" && (new RegExp(/\.(.*?)/g)).test(elementTag)) {
            this.$ele = document.getElementsByClassName(elementTag.substring(1));
        } else if (typeof elementTag == "string" && (new RegExp(/\#(.*?)/g)).test(elementTag)) {
            this.$ele = document.getElementById(elementTag.substring(1));
        } else if (typeof elementTag == "string" && (new RegExp(/\<(.*?)\/\>/g)).test(elementTag)) {
            this.$ele = document.createElement(elementTag.replace("<", "").replace("/>", ""));
        } else if (typeof elementTag == "string") {
            this.$ele = document.getElementsByTagName(elementTag);
        } else if (elementTag instanceof HTMLElement) {
            this.$ele = elementTag;
        } else {
            this.$ele = null;
        }
        this.eventMgr = new EventManage(this);
    }
    get current() {
        return this.$ele;
    }
    get children() {
        const children: $Element[] = [];
        if (this.current instanceof HTMLElement) {
            for (let i = 0; i < this.current.children.length; i++) {
                children.push(new $Element(this.current.children[i]))
            }
        } else if (this.current instanceof HTMLCollection) {
            for (let i = 0; i < this.current.length; i++) {
                for (let j = 0; j < this.current[i].children.length; j++) {
                    children.push(new $Element(this.current[i].children[j]))
                }
            }
        }
        return children;
    }
    /**
     * 传入进来的元素是否是自己的同类
     */
    is(ele: HTMLElement | Element) {
        if (this.current instanceof HTMLElement) {
            return this.current === ele;
        } else if (this.current instanceof HTMLCollection) {
            let is = false;
            for (let i = 0; i < this.current.length; i++) {
                if (this.current[i] === ele) {
                    is = true;
                    break;
                }
            }
            return is;
        }
    }
    getChild(elementTag: string | HTMLElement | Element) {
        return new $Element(elementTag);
    }
    empty() {
        for (let i = 0; i < this.children.length; i++) {
            this.emptyDom(this.children[i]);
        }
        this.emptyTextContent();
    }
    private emptyTextContent() {
        if (this.current instanceof HTMLElement) {
            this.current.textContent = "";
        } else if (this.current instanceof HTMLCollection) {
            for (let i = 0; i < this.current.length; i++) {
                this.current[i].textContent = "";
            }
        }
    }
    private emptyDom(ele: $Element) {
        const elChildrens = ele.children;
        for (let i = 0; i < elChildrens.length; i++) {
            this.eventMgr.removeDOMEventListener(ele)
        }
    }
    private setDOMStyle(ele: HTMLElement | Element, styleCode: string, propName?: string) {
        if (propName) {
            (<any>ele).style[propName] = styleCode;
        } else {
            ele.setAttribute("style", styleCode);
        }
    }
    private addDOMClassName(ele: HTMLElement | Element, className: string) {
        ele.setAttribute("class", (ele.getAttribute("class") || "") + " " + className);

    }

    private removeDOMClassName(ele: HTMLElement | Element, className: string) {
        ele.setAttribute("class", ele.getAttribute("class")?.replace(" " + className, "") || "");
    }

    private removeDOMChild(ele: HTMLElement | Element, child: $Element) {
        if (child.current instanceof HTMLElement) {
            ele.removeChild(child.current);
        } else if (child.current instanceof HTMLCollection) {
            for (let i = 0; i < child.current.length; i++) {
                ele.removeChild(child.current[i]);
            }
        }
    }
    private addDOMChild(ele: HTMLElement | Element, child: $Element) {
        if (child.current instanceof HTMLElement) {
            ele.appendChild(child.current);
        } else if (child.current instanceof HTMLCollection) {
            for (let i = 0; i < child.current.length; i++) {
                ele.appendChild(child.current[i]);
            }
        }
    }
    appendChild(element: $Element) {
        if (this.current instanceof HTMLElement) {
            this.addDOMChild(this.current, element);
        } else if (this.current instanceof HTMLCollection) {
            for (let i = 0; i < this.current.length; i++) {
                const ele = this.current[i];
                this.addDOMChild(ele, element);
            }
        }
    }
    removeChild(element: $Element) {
        if (this.current instanceof HTMLElement) {
            this.removeDOMChild(this.current, element);
        } else if (this.current instanceof HTMLCollection) {
            for (let i = 0; i < this.current.length; i++) {
                const ele = this.current[i];
                this.removeDOMChild(ele, element);
            }
        }
    }

    setStyle(styleCode: string) {
        if (this.current instanceof HTMLElement) {
            this.setDOMStyle(this.current, styleCode)
        } else if (this.current instanceof HTMLCollection) {
            for (let i = 0; i < this.current.length; i++) {
                const ele = this.current[i];
                this.setDOMStyle(ele, styleCode)
            }
        }
    }
    private setDOMAttribute(dom: HTMLElement | Element, attrName: string, attrValue: any) {
        dom.setAttribute(attrName, attrValue);
    }
    private getDOMAttribute(dom: HTMLElement | Element, attrName: string) {
        dom.getAttribute(attrName);
    }
    attr(attrName: string, attrValue?: any) {
        if (attrValue) {
            if (this.current instanceof HTMLElement) {
                // (<any>this.current.style)[propName] = styleCode;
                this.setDOMAttribute(this.current, attrName, attrValue)
            } else if (this.current instanceof HTMLCollection) {
                for (let i = 0; i < this.current.length; i++) {
                    const ele = this.current[i];
                    this.setDOMAttribute(ele, attrName, attrValue)
                }
            }
        } else {
            if (this.current instanceof HTMLElement) {
                // (<any>this.current.style)[propName] = styleCode;
                this.getDOMAttribute(this.current, attrName)
            } else if (this.current instanceof HTMLCollection) {
                for (let i = 0; i < this.current.length; i++) {
                    const ele = this.current[i];
                    this.getDOMAttribute(ele, attrName)
                }
            }
        }
    }
    setStyleWithProp(propName: string, styleCode: string) {
        if (this.current instanceof HTMLElement) {
            // (<any>this.current.style)[propName] = styleCode;
            this.setDOMStyle(this.current, styleCode, propName)
        } else if (this.current instanceof HTMLCollection) {
            for (let i = 0; i < this.current.length; i++) {
                const ele = this.current[i];
                this.setDOMStyle(ele, styleCode, propName)
            }
        }
    }
    addClassName(className: string) {
        if (this.current instanceof HTMLElement) {
            this.addDOMClassName(this.current, className);
            // (<HTMLElement>this.current).setAttribute("class", (<HTMLElement>this.current).getAttribute("class")+" "+className);
        } else if (this.current instanceof HTMLCollection) {
            for (let i = 0; i < this.current.length; i++) {
                const ele = this.current[i];
                this.addDOMClassName(ele, className);
                // ele.setAttribute("class",ele.getAttribute("class")+" "+className);
            }
        }
    }
    removeClassName(className: string) {
        if (this.current instanceof HTMLElement) {
            this.removeDOMClassName(this.current, className);
        } else if (this.current instanceof HTMLCollection) {
            for (let i = 0; i < this.current.length; i++) {
                const ele = this.current[i];
                this.removeDOMClassName(ele, className);
            }
        }
    }
    addEventDelegate(eventName: string, fn: (event: Event) => boolean | undefined | void, target?: $Element) {

    }
    addEventListener(eventName: string, fn: (event: Event) => boolean | undefined | void) {
        this.eventMgr.addEventListener(eventName, fn);
    }
    removeEventListener(eventName: string | string[]) {
        if (eventName instanceof Array) {
            eventName.forEach(evtName => {
                this.eventMgr.removeEventListener(evtName);
            })
        } else {
            this.eventMgr.removeEventListener(eventName);
        }

    }

    removeEventDelegate(eventName: string | string[], target?: $Element) {
        if (eventName instanceof Array) {
            eventName.forEach(evtName => {
                this.eventMgr.removeEventListener(evtName);
            })
        } else {
            this.eventMgr.removeEventListener(eventName);
        }
    }
}